#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
--------------------------------------
    Author:     JiChao_Song
    Date  :     2021/12/1 21:40
    Desc  :
--------------------------------------
"""
from jsonrpcserver import method, Success
from werkzeug.security import generate_password_hash

from common.enums.response_enums import CommonResultEnums
from common.response import RPCCommonResponse, RPCSuccessResponse, RPCParamsErrorResponse
from common.utils.jwt_utils import AuthJwtWithHeaders
from common.utils.log_utils import logger
from common.utils.other_utils import get_time
from common.utils.redis_utils import get_token, delete_token, save_token_appid
from person.models.person import Person
from person.serializers.person import PersonSerializer
from platform_auth.settings import JWT_EXPIRATION_DELTA


@method(name = 'UserLogin')
def user_login(username: str, password: str, headers: dict):
    exclude_fields = ['deleted', 'deleteTime', 'password']

    queryset = Person.objects.filter(username = username, deleted = False)

    if queryset.count() == 0:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.USER_NOT_EXIST_BY_USERNAME))

    person = queryset.first()

    flag = person.check_password(password)
    if not flag:
        logger.error(f'密码: {password}')
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.CHECK_PASSWORD_FAIL))

    person.lastLoginTime = get_time()

    person.save()

    payload = dict(
        id = person.id,
        username = person.username
    )
    authJwt = AuthJwtWithHeaders(headers = headers)
    if authJwt.secret_key() is None:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.APPLICATION_NOT_EXIST_BY_APPID))

    token = authJwt.generate_jwt(payload = payload)
    serializer = PersonSerializer(person, exclude = exclude_fields)
    payload.update(serializer.data)
    payload['userId'] = person.id
    payload['expire_time'] = JWT_EXPIRATION_DELTA.strftime('%Y-%m-%d %H:%M:%S')
    payload['token'] = token

    # 存取token到redis缓存中
    save_token_appid(userId = person.id, data = payload)
    serializer = PersonSerializer(person, exclude = ['deleted', 'deleteTime', 'password'])
    return Success(RPCSuccessResponse(result = {
        'token': token,
        'userInfo': serializer.data
    }))


@method(name = 'UserLogout')
def user_logout(headers: dict):
    token = headers.get('Accesstoken')
    authJwt = AuthJwtWithHeaders(headers)
    userId = authJwt.get_user_id()
    if token:
        # 删除token
        delete_token(userId = userId)

    return Success(RPCSuccessResponse())


@method(name = 'GetUserInfo')
def user_info(headers: dict):
    """
    获取用户信息
    :param headers:
    :return:
    """
    token = headers.get('Accesstoken')
    logger.info(f'token {token}')
    authJwt = AuthJwtWithHeaders(headers = headers)
    userId = authJwt.get_user_id()
    logger.info(f'userId {userId}')
    queryset = Person.objects.filter(id = userId, deleted = False)
    logger.info(queryset.first())

    if queryset.count() == 0:
        logger.info(f'用户id: {userId}')
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.USER_NOT_EXIST_BY_USER_ID))
    serializer = PersonSerializer(queryset.first(), exclude = ['deleted', 'deleteTime', 'password'])
    return Success(RPCSuccessResponse(result = serializer.data))


@method(name = 'UserRegister')
def user_register(**kwargs):
    body: dict = kwargs
    username, password = body.get('username'), body.get('password')
    phone, email = body.get('phone'), body.get('email')
    queryset = Person.objects.filter(username = username, deleted = False)

    if username is None or username == '':
        return Success(RPCParamsErrorResponse(message = 'username不能为空'))
    if password is None or password == '':
        return Success(RPCParamsErrorResponse(message = 'password不能为空'))

    if queryset.count() != 0:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.USERNAME_IS_EXIST))
    if phone and phone != '':

        queryset_phone = Person.objects.filter(phone = phone, deleted = False)

        if queryset_phone.count() != 0:
            return Success(RPCCommonResponse(codeEnums = CommonResultEnums.PHONE_IS_USED))

    data = {
        'username': username,
        'password': generate_password_hash(password),
        'phone': phone,
        'email': email

    }

    person = Person.objects.create(**data)

    serializer = PersonSerializer(person, exclude = ['deleted', 'deleteTime', 'password'])

    return Success(RPCSuccessResponse(result = serializer.data))


def check_token_util(headers: dict):
    """校验token"""
    token = headers.get('Accesstoken')
    appId = headers.get('Appid')
    logger.info(f'token {token}')
    authJwt = AuthJwtWithHeaders(headers = headers)
    userId = authJwt.get_user_id()
    logger.info(f'userId {userId}')

    if token is None or token == '' or not get_token(userId = userId, token = token,) or authJwt.secret_key() is None or authJwt.verify_jwt() is None:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.TOKEN_INVALID))


@method(name = 'CheckToken')
def check_token(headers: dict):
    """校验token"""
    token = headers.get('Accesstoken')
    appId = headers.get('Appid')
    logger.info(f'token {token}')
    authJwt = AuthJwtWithHeaders(headers = headers)
    userId = authJwt.get_user_id()
    logger.info(f'userId {userId}')

    if token is None or token == '':
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.TOKEN_INVALID))
    if not get_token(userId = userId, token = token):
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.TOKEN_INVALID))
    if authJwt.secret_key() is None:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.APPLICATION_NOT_EXIST_BY_APPID))
    if authJwt.verify_jwt() is None:
        return Success(RPCCommonResponse(codeEnums = CommonResultEnums.TOKEN_INVALID))
    return Success(RPCSuccessResponse())
